using System;
using System.IO;
using System.Text;
using System.Reflection;
using System.Reflection;
using System.Diagnostics;
using System.Globalization;
using System.ComponentModel;
using System.Security.Permissions;
using System.Runtime.InteropServices;
using System.Runtime.CompilerServices;
using Microsoft.Win32;
using System.Windows.Forms;
using System.Collections.Generic;
using System.Drawing;



[assembly:AssemblyVersion(@"1.0.0.0")]
[assembly: AssemblyKeyFile(@"..\..\..\ecomet.snk")]

namespace eComet
{
    [Guid("66ABF5B3-9113-4010-92C4-B66CD2D86121")]
	public class CommandShellExtension : IShellExtInit, IContextMenu
	{
        const string guid = "{66ABF5B3-9113-4010-92C4-B66CD2D86121}";

#region Protected Members
		protected IDataObject m_dataObject = null;
		uint m_hDrop = 0;
		MenuItem[] m_items;
        String processName = "cometag";
        int appId = 0;
        List<object> objects = new List<object>();
        List<int> indexes = new List<int>();
        Dictionary<uint, string> dict = new Dictionary<uint, string>();
#endregion

#region IContextMenu

        public void codigos(uint hMenu, uint iMenu)
        {
            //Module module = ModuleManager.getInstance(@"C:\Users\psykohack\Documents\TRABAJO\COMET\Codigo\eCometPluginExample\bin\Debug\eCometPluginExample.dll");
            //module.Menu(hMenu, iMenu);
            //uint hmnuPopup = Helpers.CreatePopupMenu();
            //MENUITEMINFO mii = new MENUITEMINFO();
            //mii.cbSize = 48;
            //mii.fMask = (uint)MIIM.TYPE | (uint)MIIM.STATE | (uint)MIIM.SUBMENU;
            //mii.hSubMenu = (int)hmnuPopup;
            //mii.fType = (uint)MF.STRING;
            //mii.dwTypeData = "eCometa";
            //mii.fState = (uint)MF.ENABLED;
            //Helpers.InsertMenuItem(hMenu, (uint)iMenu, 1, ref mii);
        }


        public bool CheckConfig(ECometConfig config,ref uint nselectedt,ref int typeDirOrFilet,ref List<String> pathst,ref List<String> extensionst)
        {
            bool exit = false ;
            try
            {
                if (config.DisplayMenu)
                {
                    if (!config.SupportAll)
                    {
                        if (nselectedt == 1)
                        {
                            switch (typeDirOrFilet)
                            {
                                case 0:
                                    if (config.SupportOneFile)
                                    {
                                        if (!(config.ExtensionsSupported.Equals("*") || config.ExtensionsSupported.Equals(String.Empty)))
                                        {
                                            if (Array.IndexOf(config.ExtensionsSupported.ToUpper().Split(','), Path.GetExtension(pathst[0]).ToUpper()) >= 0)
                                            {
                                                exit = true;
                                            }
                                            else
                                            {
                                                exit = false;
                                            }
                                        }
                                        else
                                        {
                                            exit = true;
                                        }
                                    }
                                    else
                                    {
                                        exit = false;
                                    }
                                    break;
                                case 1:
                                    if (config.SupportOneDirectory)
                                    {
                                        exit = true;
                                    }
                                    else
                                    {
                                        exit = false;
                                    }
                                    break;
                            }
                        }
                        else
                        {
                            switch (typeDirOrFilet)
                            {
                                case 0:
                                    if (config.SupportMultipleFiles)
                                    {
                                        if (!(config.ExtensionsSupported.Equals("*") || config.ExtensionsSupported.Equals(String.Empty)))
                                        {
                                            List<String> temp = new List<String>();
                                            List<String> exts = new List<String>();
                                            String ext;
                                            foreach (String path in pathst)
                                            {
                                                if (!(Array.IndexOf(config.ExtensionsSupported.ToUpper().Split(','), ext = Path.GetExtension(path).ToUpper()) >= 0))
                                                {
                                                    temp.Add(path);
                                                }
                                                else
                                                {
                                                    if (!exts.Contains(ext))
                                                        exts.Add(ext);
                                                }
                                            }
                                            foreach (String tmp in temp)
                                            {
                                                pathst.Remove(tmp);
                                            }
                                            if (pathst.Count > 0)
                                            {
                                                extensionst = exts;
                                                nselectedt = (uint)pathst.Count;
                                                exit = true;
                                            }
                                            else
                                            {
                                                exit = false;
                                            }
                                        }
                                        else
                                        {
                                            exit = true;
                                        }
                                    }
                                    else
                                    {
                                        exit = false;
                                    }
                                    break;
                                case 1:
                                    if (config.SupportMultipleDirectories)
                                    {
                                        exit = true;
                                    }
                                    else
                                    {
                                        exit = false;
                                    }
                                    break;
                                case 2:
                                    if (config.SupportFilesAndDirectoriesMixed)
                                    {
                                        if (!(config.ExtensionsSupported.Equals("*") || config.ExtensionsSupported.Equals(String.Empty)))
                                        {
                                            bool hayArchivos = false;
                                            List<String> temp = new List<String>();
                                            List<String> exts = new List<String>();
                                            String ext;
                                            foreach (String path in pathst)
                                            {
                                                if (!IsDirectory(path))
                                                {
                                                    if (!(Array.IndexOf(config.ExtensionsSupported.ToUpper().Split(','), ext = Path.GetExtension(path).ToUpper()) >= 0))
                                                    {
                                                        temp.Add(path);
                                                    }
                                                    else
                                                    {
                                                        if (!exts.Contains(ext))
                                                            exts.Add(ext);
                                                        hayArchivos = true;
                                                    }
                                                }
                                            }
                                            foreach (String tmp in temp)
                                            {
                                                pathst.Remove(tmp);
                                            }
                                            if (!hayArchivos)
                                            {
                                                typeDirOrFilet = 1;
                                            }
                                            extensionst = exts;
                                            nselectedt = (uint)pathst.Count;
                                            exit = true;
                                        }
                                        else
                                        {
                                            exit = true;
                                        }
                                    }
                                    else if (config.SupportMultipleFiles)
                                    {
                                        if (!(config.ExtensionsSupported.Equals("*") || config.ExtensionsSupported.Equals(String.Empty)))
                                        {
                                            bool hayArchivos = false;
                                            List<String> temp = new List<String>();
                                            List<String> exts = new List<String>();
                                            String ext;
                                            foreach (String path in pathst)
                                            {
                                                if (!IsDirectory(path))
                                                {
                                                    if (!(Array.IndexOf(config.ExtensionsSupported.ToUpper().Split(','), ext = Path.GetExtension(path).ToUpper()) >= 0))
                                                    {
                                                        temp.Add(path);
                                                    }
                                                    else
                                                    {
                                                        if (!exts.Contains(ext))
                                                            exts.Add(ext);
                                                        hayArchivos = true;
                                                    }
                                                }
                                            }
                                            foreach (String tmp in temp)
                                            {
                                                pathst.Remove(tmp);
                                            }
                                            if (hayArchivos)
                                            {
                                                typeDirOrFilet = 1;
                                                extensionst = exts;
                                                nselectedt = (uint)pathst.Count;
                                                exit = true;
                                            }
                                            else
                                            {
                                                exit = false;
                                            }
                                        }
                                        else
                                        {
                                            exit = true;
                                        }
                                    }
                                    else
                                    {
                                        exit = false;
                                    }
                                    break;
                            }
                        }
                    }
                    else
                    {
                        exit = true;
                    }
                }
            }
            catch (Exception e)
            {
                MessageBox.Show("Error1");
                MessageBox.Show(e.Message);
            }
            return exit;
        }

        


        int IContextMenu.QueryContextMenu(uint hMenu, uint iMenu, int idCmdFirst, int idCmdLast, uint uFlags)
		{
            //MessageBox.Show("Eyyy!!!");
            int id = 0;
            id += idCmdFirst;
            uint pos = 0;
            try
            {
                if ((uFlags & 0xf) == 0 || (uFlags & (uint)CMF.CMF_EXPLORE) != 0)
                {
                    //MessageBox.Show("Holas2");
                    uint nselected = Helpers.DragQueryFile(m_hDrop, 0xffffffff, null, 0);
                    //MessageBox.Show("Holas2.1");
                    StringBuilder sb = new StringBuilder(1024);
                    //MessageBox.Show("Holas2.2");
                    String directory = "";
                    int cont = 0;
                    int typeDirOrFile = 0;
                    List<String> paths = new List<String>();
                    List<String> extensions = new List<String>();
                    //MessageBox.Show("Holas2.3");
                    String direc = Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles) + @"\eComet\icon.bmp";
                    //MessageBox.Show(direc);
                    Bitmap bmp = new Bitmap(direc);
                    //MessageBox.Show("Holas2.5");
                    IntPtr ip = bmp.GetHbitmap();

                    //MessageBox.Show("Holas3");

                    uint hmnuPopup = Helpers.CreatePopupMenu();
                    MENUITEMINFO mii = new MENUITEMINFO();
                    mii.cbSize = 48;
                    mii.fMask = (uint)MIIM.TYPE | (uint)MIIM.STATE | (uint)MIIM.SUBMENU | (uint)MIIM.CHECKMARKS;
                    mii.hSubMenu = (int)hmnuPopup;
                    mii.fType = (uint)MF.STRING;
                    mii.dwTypeData = "eComet";
                    mii.fState = (uint)MF.ENABLED;
                    mii.hbmpChecked = (int)ip;
                    mii.hbmpItem = (int)ip;
                    mii.hbmpUnchecked = (int)ip;
                    Helpers.InsertMenuItem(hMenu, (uint)iMenu, 1, ref mii);

                    //MessageBox.Show("Holas4");

                    for (int i = 0; i < nselected; i++)
                    {
                        //MessageBox.Show("Holas5");

                        Helpers.DragQueryFile(m_hDrop, (uint)i, sb, sb.Capacity + 1);
                        directory = sb.ToString();
                        paths.Add(directory);
                        if (IsDirectory(directory))
                        {
                            cont++;
                        }
                        else
                        {
                            if (directory.Contains("."))
                            {
                                String ext = Path.GetExtension(directory).ToUpper();
                                if (!extensions.Contains(ext))
                                {
                                    extensions.Add(ext);
                                }
                            }
                        }
                    }
                    if (cont == nselected)
                    {
                        typeDirOrFile = 1;
                    }
                    else if (cont == 0)
                    {
                        typeDirOrFile = 0;
                    }
                    else
                    {
                        typeDirOrFile = 2;
                    }
                    //MessageBox.Show("Holas6");
                    int index = 0;
                    object module = null;
                    IECometPlugIn plugIn = null;
                    String dir = Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles) + @"\eComet\Plugins\";
                    ECometConfig config;
                    List<String> pathst;
                    List<String> extensionst;
                    int typeDirOrFilet;
                    uint nselectedt;
                    uint submenu = 0;
                    //MessageBox.Show("Paso1");
                    Dictionary<String, uint> popups = new Dictionary<String, uint>();
                    foreach (String archivo in Directory.GetFiles(dir))
                    {
                        //String nomArch = archivo;
                        String nomArch = Path.GetFileName(archivo);
                        if (!nomArch.Equals("eCometPlugin.dll") && !nomArch.Equals("eCometPluginLoader.dll"))
                        {
                            string extension = Path.GetExtension(archivo).ToUpper();
                            if (extension.Equals(".DLL"))
                            {
                                //MessageBox.Show("Paso2 " + nomArch + " -> "+archivo);
                                module = ModuleManager.getInstance(archivo, "eComet.ECometPlugIn");
                                //MessageBox.Show("Pase el paso 2");
                                if (module != null)
                                {
                                    bool esInstancia;
                                    try
                                    {
                                        plugIn = (IECometPlugIn)module;
                                        esInstancia = true;
                                    }
                                    catch
                                    {
                                        esInstancia = false;
                                    }
                                    if (esInstancia)
                                    {
                                        config = plugIn.Configuration();
                                        pathst = new List<String>(paths.ToArray());
                                        extensionst = extensions;
                                        typeDirOrFilet = typeDirOrFile;
                                        nselectedt = nselected;
                                        if (CheckConfig(config, ref nselectedt, ref typeDirOrFilet, ref pathst, ref extensionst))
                                        {
                                            objects.Add(module);
                                            if (!popups.ContainsKey(config.ApplicationName))
                                            {
                                                index += plugIn.PrivateStart(hmnuPopup, iMenu, id + index, nselectedt, typeDirOrFilet, pathst, extensionst, index, config, ref submenu, false);
                                                indexes.Add(index);
                                                popups.Add(config.ApplicationName, submenu);
                                            }
                                            else
                                            {
                                                index += plugIn.PrivateStart(popups[config.ApplicationName], iMenu, id + index, nselectedt, typeDirOrFilet, pathst, extensionst, index, config, ref submenu, true);
                                                indexes.Add(index);
                                            }
                                        }
                                    }
                                }
                                else
                                {
                                    //MessageBox.Show("Paso4 ");
                                }
                            }
                        }
                        else
                        {
                            //MessageBox.Show("Si esta");
                        }
                    }
                    //module = ModuleManager.getInstance(@"C:\Users\psykohack\Documents\TRABAJO\COMET\Codigo\eCometPluginExample\bin\Debug\eCometPluginExample.dll", "eComet.ECometPlugIn");
                    //if (module != null)
                    //{
                    //    objects.Add(module);
                    //    plugIn = (IECometPlugIn)module;
                    //    index += plugIn.PrivateStart(hmnuPopup, iMenu, id, nselected, typeDirOrFile, paths, extensions, index);
                    //    indexes.Add(index);
                    //}
                    //module = ModuleManager.getInstance(@"C:\Users\psykohack\Documents\TRABAJO\COMET\Codigo\eCometPluginTagger\bin\Debug\eCometPluginTagger.dll", "eComet.ECometPlugIn");
                    //if (module != null)
                    //{
                    //    objects.Add(module);
                    //    plugIn = (IECometPlugIn)module;
                    //    index += plugIn.PrivateStart(hmnuPopup, iMenu, id + index, nselected, typeDirOrFile, paths, extensions, index);
                    //    indexes.Add(index);
                    //}
                    //MessageBox.Show((index + 1).ToString());
                    return index + 1;
                }
            }
            catch (ArgumentException e)
            { 
            }
            catch (ReflectionTypeLoadException e)
            {
                String error = "";
                foreach (Exception ex in e.LoaderExceptions)
                {
                    error += ex.Message + "\n";
                }
                MessageBox.Show(error);
            }
            catch (Exception e)
            {
                String valerror = "ERROR SET:\n" + e.GetType().Name + "\n" + e.Source + "\n" + e.TargetSite.Name + "\n" + e.Message + "\n" + e.StackTrace;
                MessageBox.Show(valerror);
            }
                //if (nselected == 1)
                //{
                //    try
                //    {
                //        codigos(hMenu, hMenu);
                //        Module module = ModuleManager.getInstance(@"C:\Users\psykohack\Documents\TRABAJO\COMET\Codigo\eCometPluginExample\bin\Debug\eCometPluginExample.dll");
                //        module.Menu(hMenu, iMenu);
                //        object module = ModuleManager.getInstance(@"C:\Users\psykohack\Documents\TRABAJO\COMET\Codigo\eCometPluginExample\bin\Debug\eCometPluginExample.dll", "eComet.ECometPlugIn");
                //        if (module != null)
                //        {
                //            IECometPlugIn plugIn = (IECometPlugIn)module;
                //            plugIn.Menu(hMenu, iMenu);
                //            plugIn.Imprime();
                //        }
                        
                    //}
                    //catch (Exception e)
                    //{
                    //    MessageBox.Show(e.Message);
                    //}
                    //uint hmnuPopup = Helpers.CreatePopupMenu();
                    //MENUITEMINFO mii = new MENUITEMINFO();
                    //mii.cbSize = 48;
                    //mii.fMask = (uint)MIIM.TYPE | (uint)MIIM.STATE | (uint)MIIM.SUBMENU;
                    //mii.hSubMenu = (int)hmnuPopup;
                    //mii.fType = (uint)MF.STRING;
                    //mii.dwTypeData = "eComet";
                    //mii.fState = (uint)MF.ENABLED;
                    //Helpers.InsertMenuItem(hMenu, (uint)iMenu, 1, ref mii);

                    //StringBuilder sb = new StringBuilder(1024);
                    //Helpers.DragQueryFile(m_hDrop, 0, sb, sb.Capacity + 1);
                    //string directory = sb.ToString();

                    //if (IsDirectory(directory))
                    //{
                    //    string[] dirs = directory.Split('\\');
                    //    string folder = dirs[dirs.Length - 1];
                    //    string folderAnt = dirs[dirs.Length - 2];
                    //    dict[pos] = "/type dir /path " + directory + " /setgen " + folder;
                    //    AddMenuItem(hmnuPopup, "Set Genere as " + folder, id++, pos++);
                    //    dict[pos] = "/type dir /path " + directory + " /setalb " + folder;
                    //    AddMenuItem(hmnuPopup, "Set Album as " + folder, id++, pos++);
                    //    dict[pos] = "/type dir /path " + directory + " /setart " + folder;
                    //    AddMenuItem(hmnuPopup, "Set Artist as " + folder, id++, pos++);
                    //    dict[pos] = "/type dir /path " + directory + " /setgen " + folderAnt + " " + folder;
                    //    AddMenuItem(hmnuPopup, "Set Genere as " + folderAnt + " " + folder, id++, pos++);
                    //    dict[pos] = "/type dir /path " + directory + " /setalb " + folderAnt + " " + folder;
                    //    AddMenuItem(hmnuPopup, "Set Album as " + folderAnt + " " + folder, id++, pos++);
                    //    dict[pos] = "/type dir /path " + directory + " /owngen";
                    //    AddMenuItem(hmnuPopup, "Set Genere", id++, pos++);
                    //    dict[pos] = "/type dir /path " + directory + " /ownalb";
                    //    AddMenuItem(hmnuPopup, "Set Album", id++, pos++);
                    //    dict[pos] = "/type dir /path " + directory + " /ownart";
                    //    AddMenuItem(hmnuPopup, "Set Artist", id++, pos++);
                    //    dict[pos] = "/type dir /path " + directory + " /all";
                    //    AddMenuItem(hmnuPopup, "Edit All", id++, pos++);
                    //}
                    //else
                    //{
                    //    string[] arch = directory.Split('\\');
                    //    string archivo = arch[arch.Length - 1];
                    //    string nombre = "";
                    //    if (archivo.Contains("."))
                    //    {
                    //        nombre = archivo.Substring(0, archivo.LastIndexOf('.'));
                    //    }
                    //    else
                    //    {
                    //        nombre = archivo;
                    //    }
                    //    if (archivo.Contains("-"))
                    //    {
                    //        string[] datos = nombre.Split('-');
                    //        dict[pos] = "/type file /path " + directory + " /setart " + datos[datos.Length - 2].Trim();
                    //        AddMenuItem(hmnuPopup, "Set Artist as " + datos[datos.Length - 2].Trim(), id++, pos++);
                    //        dict[pos] = "/type file /path " + directory + " /setalb " + datos[datos.Length - 2].Trim();
                    //        AddMenuItem(hmnuPopup, "Set Album as " + datos[datos.Length - 2].Trim(), id++, pos++);
                    //        dict[pos] = "/type file /path " + directory + " /setson " + datos[datos.Length - 1].Trim();
                    //        AddMenuItem(hmnuPopup, "Set Song as " + datos[datos.Length - 1].Trim(), id++, pos++);
                    //        dict[pos] = "/type file /path " + directory + " /owngen";
                    //        AddMenuItem(hmnuPopup, "Set Genere", id++, pos++);
                    //        dict[pos] = "/type file /path " + directory + " /ownalb";
                    //        AddMenuItem(hmnuPopup, "Set Album", id++, pos++);
                    //        dict[pos] = "/type file /path " + directory + " /ownart";
                    //        AddMenuItem(hmnuPopup, "Set Artist", id++, pos++);
                    //        dict[pos] = "/type file /path " + directory + " /dir \\" + datos[datos.Length - 2].Trim() + "\\" + archivo;
                    //        AddMenuItem(hmnuPopup, "Place on \\" + datos[datos.Length - 2].Trim() + "\\", id++, pos++);
                    //        dict[pos] = "/type file /path " + directory + " /all";
                    //        AddMenuItem(hmnuPopup, "Edit All", id++, 1);
                    //    }
                    //    else
                    //    {
                    //        dict[pos] = "/type file /path " + directory + " /setson " + nombre.Trim();
                    //        AddMenuItem(hmnuPopup, "Set Song as " + nombre.Trim(), id++, pos++);
                    //        dict[pos] = "/type file /path " + directory + " /owngen";
                    //        AddMenuItem(hmnuPopup, "Set Genere", id++, pos++);
                    //        dict[pos] = "/type file /path " + directory + " /ownalb";
                    //        AddMenuItem(hmnuPopup, "Set Album", id++, pos++);
                    //        dict[pos] = "/type file /path " + directory + " /ownart";
                    //        AddMenuItem(hmnuPopup, "Set Artist", id++, pos++);
                    //        dict[pos] = "/type file /path " + directory + " /all";
                    //        AddMenuItem(hmnuPopup, "Edit All", id++, pos++);
                    //    }
                    //}
                    //id = PopulateMenu(hmnuPopup, idCmdFirst + id);
                //}
                //else
                //{
                //    uint hmnuPopup = Helpers.CreatePopupMenu();
                //    MENUITEMINFO mii = new MENUITEMINFO();
                //    mii.cbSize = 48;
                //    mii.fMask = (uint)MIIM.TYPE | (uint)MIIM.STATE | (uint)MIIM.SUBMENU;
                //    mii.hSubMenu = (int)hmnuPopup;
                //    mii.fType = (uint)MF.STRING;
                //    mii.dwTypeData = "eComet";
                //    mii.fState = (uint)MF.ENABLED;
                //    Helpers.InsertMenuItem(hMenu, (uint)iMenu, 1, ref mii);
                //    StringBuilder sb = new StringBuilder(1024);
                //    string directory = "";
                //    int cont = 0;
                //    string paths = "";
                //    for (int i = 0; i < nselected; i++)
                //    {
                //        Helpers.DragQueryFile(m_hDrop, (uint)i, sb, sb.Capacity + 1);
                //        directory = sb.ToString();
                //        paths += directory + ";";
                //        if (IsDirectory(directory))
                //        {
                //            cont++;
                //        }
                //    }
                //    if (cont == nselected)
                //    {
                //        dict[pos] = "/type dirs /path " + paths + " /setgen";
                //        AddMenuItem(hmnuPopup, "Set Genere as (FolderName)", id++, pos++);
                //        dict[pos] = "/type dirs /path " + paths + " /setalb";
                //        AddMenuItem(hmnuPopup, "Set Album as (FolderName)", id++, pos++);
                //        dict[pos] = "/type dirs /path " + paths + " /setart";
                //        AddMenuItem(hmnuPopup, "Set Artist as (FolderName)", id++, pos++);
                //        dict[pos] = "/type dirs /path " + paths + " /setgenboth";
                //        AddMenuItem(hmnuPopup, "Set Genere as (LastFolder) (CurrentName)", id++, pos++);
                //        dict[pos] = "/type dirs /path " + paths + " /setalbboth";
                //        AddMenuItem(hmnuPopup, "Set Album as (LastFolder) (CurrentName)", id++, pos++);
                //        dict[pos] = "/type dirs /path " + paths + " /owngen";
                //        AddMenuItem(hmnuPopup, "Set Genere", id++, pos++);
                //        dict[pos] = "/type dirs /path " + paths + " /ownalb";
                //        AddMenuItem(hmnuPopup, "Set Album", id++, pos++);
                //        dict[pos] = "/type dirs /path " + paths + " /ownart";
                //        AddMenuItem(hmnuPopup, "Set Artist", id++, pos++);
                //        dict[pos] = "/type dirs /path " + paths + " /all";
                //        AddMenuItem(hmnuPopup, "Edit All", id++, pos++);
                //    }
                //    else if (cont == 0)
                //    {
                //        dict[pos] = "/type files /path " + paths + " /setart";
                //        AddMenuItem(hmnuPopup, "Set Artist as (Name) - ***", id++, pos++);
                //        dict[pos] = "/type files /path " + paths + " /setalb";
                //        AddMenuItem(hmnuPopup, "Set Album as (Name) - ***", id++, pos++);
                //        dict[pos] = "/type files /path " + paths + " /setson";
                //        AddMenuItem(hmnuPopup, "Set Song as (FileName)", id++, pos++);
                //        dict[pos] = "/type files /path " + paths + " /owngen";
                //        AddMenuItem(hmnuPopup, "Set Genere", id++, pos++);
                //        dict[pos] = "/type files /path " + paths + " /ownalb";
                //        AddMenuItem(hmnuPopup, "Set Album", id++, pos++);
                //        dict[pos] = "/type files /path " + paths + " /ownart";
                //        AddMenuItem(hmnuPopup, "Set Artist", id++, pos++);
                //        dict[pos] = "/type files /path " + paths + " /dir";
                //        AddMenuItem(hmnuPopup, "Place on \\(Name) - ***\\", id++, pos++);
                //        dict[pos] = "/type files /path " + paths + " /all";
                //        AddMenuItem(hmnuPopup, "Edit All", id++, 1);
                //    }
                //    else
                //    {
                //        dict[pos] = "/type dirfile /path " + paths + " /owngen";
                //        AddMenuItem(hmnuPopup, "Set Genere", id++, pos++);
                //        dict[pos] = "/type dirfile /path " + paths + " /ownalb";
                //        AddMenuItem(hmnuPopup, "Set Album", id++, pos++);
                //        dict[pos] = "/type dirfile /path " + paths + " /ownart";
                //        AddMenuItem(hmnuPopup, "Set Artist", id++, pos++);
                //        dict[pos] = "/type dirfile /path " + paths + " /all";
                //        AddMenuItem(hmnuPopup, "Edit All", id++, pos++);
                //    }
                //}
            
            //return (int)pos+1;
            return 0;
		}

        void AddMenuItem(uint hMenu, string text, int id, uint position)
        {
            MENUITEMINFO mii = new MENUITEMINFO();
            mii.cbSize = 48;
            mii.fMask = (uint)MIIM.ID | (uint)MIIM.TYPE | (uint)MIIM.STATE;
            mii.wID = id;
            mii.fType = (uint)MF.STRING;
            mii.dwTypeData = text;
            mii.fState = (uint)MF.ENABLED;
            Helpers.InsertMenuItem(hMenu, position, 1, ref mii);
        }

        private int PopulateMenu(uint hMenu, int id)
        {
            //int status = RunProcess(@"C:\Program Files\Git\bin\git", "rev-parse --cdup");
            //int status = 0;

            //if (status < 0)
            //{
            //    AddMenuItem(hMenu, "Cannot find git", id++, pos++);
            //}

            //if (status > 0)
            //{
            //    AddMenuItem(hMenu, "Initialize a git repo", id++, pos++);
            //}
            //else if (status == 0)
            //{
            //    AddMenuItem(hMenu, "Git Actions", id++, pos++);
            //}

            ////AddMenuItem(hMenu, "Clone Git Repository", id++, pos++);
            ////AddMenuItem(hMenu, "Create Git Repository", id++, 1);

            return id;
        }

        private bool IsDirectory(string file)
        {
            FileAttributes attr = File.GetAttributes(file);
            //detect whether its a directory or file
            if ((attr & FileAttributes.Directory) == FileAttributes.Directory)
                return true;
            else
                return false;
        }

        private int RunProcess(string command, string args)
        {
            var proc = new Process();
            proc.StartInfo.WindowStyle = ProcessWindowStyle.Normal;
            proc.StartInfo.FileName = command;
            if (args != String.Empty)
            {
                proc.StartInfo.Arguments = args;
            }

            try
            {
                proc.Start();
                //proc.WaitForExit();
            }
            catch (Win32Exception e)
            {
                return -1;
            }

            //return proc.ExitCode;
            return 0;
        }
		
		void IContextMenu.GetCommandString(int idCmd, uint uFlags, int pwReserved, StringBuilder commandString, int cchMax)
		{
            switch (uFlags)
            {
                case (uint)GCS.VERB:
                    commandString = new StringBuilder(m_items[idCmd - 1].Command.Substring(1, cchMax - 1));
                    break;
                case (uint)GCS.HELPTEXT:
                    commandString = new StringBuilder(m_items[idCmd - 1].HelpText.Substring(1, cchMax));
                    break;
                case (uint)GCS.VALIDATE:
                    break;
            }
		}

        public void cuadro()
        {
            //ECometPlugIn ec = new ECometPlugIn();
            //MessageBox.Show(ec.Suma(1, 2).ToString());
            //Module module = ModuleManager.getInstance(@"C:\Users\psykohack\Documents\TRABAJO\COMET\Codigo\eCometPluginExample\bin\Debug\eCometPluginExample.dll");
            //MessageBox.Show(module.getText());
        }
		
        //void IContextMenu.InvokeCommand(IntPtr pici)
        void IContextMenu.InvokeCommand([In] ref CommandInfo pici)
		{
            //MessageBox.Show(((int)pici.lpVerb).ToString());
            int index = (int)pici.lpVerb;
            if (index >= 0 && index < 1000)
            {
                try
                {
                    //uint index = (uint)pici.lpVerb;

                    int desde = 0;
                    int cont = 0;
                    foreach (int val in indexes)
                    {
                        if (index >= desde && index < val)
                        {
                            break;
                        }
                        else
                        {
                            desde = val;
                        }
                        cont++;
                    }
                    int opcion = index - desde;
                    //MessageBox.Show(opcion.ToString()+" "+cont.ToString());
                    if (cont >= 0 && cont < objects.Count)
                    {
                        IECometPlugIn plugIn = (IECometPlugIn)objects[cont];
                        plugIn.Actions(opcion);
                        plugIn = null;
                    }
                    objects = null;
                    //IDisposable a = (IDisposable)plugIn;
                    //a.Dispose();
                    //MessageBox.Show(opcion.ToString());
                    //MessageBox.Show(dict[index-1]);
                    //RunProcess(processName, dict[index - 1]);
                    //cuadro();
                }
                catch (Exception e)
                {
                    String valerror = "ERROR GET:\n" + e.GetType().Name + "\n" + e.Source + "\n" + e.TargetSite.Name + "\n" + e.Message + "\n" + e.StackTrace;
                    MessageBox.Show(valerror);
                }
            }
            else
            {
                objects = null;
            }
            /*
			try
			{
                Type typINVOKECOMMANDINFO = Type.GetType("CommandShellExtension.INVOKECOMMANDINFO");
				INVOKECOMMANDINFO ici = (INVOKECOMMANDINFO)Marshal.PtrToStructure(pici, typINVOKECOMMANDINFO);
                MessageBox.Show(ici.verb.ToString());
			}
			catch(Exception e)
			{
                MessageBox.Show(e.Message);
			}
            */
		}
#endregion

#region IShellExtInit
		int	IShellExtInit.Initialize (IntPtr pidlFolder, IntPtr lpdobj, uint hKeyProgID)
		{
            try
            {
                m_dataObject = null;
                if (lpdobj != (IntPtr)0)
                {
                    // Get info about the directory
                    m_dataObject = (IDataObject)Marshal.GetObjectForIUnknown(lpdobj);
                    FORMATETC fmt = new FORMATETC();
                    fmt.cfFormat = CLIPFORMAT.CF_HDROP;
                    fmt.ptd = 0;
                    fmt.dwAspect = DVASPECT.DVASPECT_CONTENT;
                    fmt.lindex = -1;
                    fmt.tymed = TYMED.TYMED_HGLOBAL;
                    STGMEDIUM medium = new STGMEDIUM();
                    m_dataObject.GetData(ref fmt, ref medium);
                    m_hDrop = medium.hGlobal;


                    // Now retrieve the menu information from the registry
                    RegistryKey sc = Registry.LocalMachine;
                    sc = sc.OpenSubKey("Software\\Microsoft\\ShellCmd", true);
                    if (sc.SubKeyCount > 0)
                    {
                        m_items = new MenuItem[sc.SubKeyCount];
                        int i = 0;
                        foreach (string name in sc.GetSubKeyNames())
                        {
                            try
                            {
                                RegistryKey item = sc.OpenSubKey(name, true);
                                string command = (string)item.GetValue("");
                                MenuItem m = new MenuItem();
                                m.Text = name;
                                m.Command = command;
                                m_items[i] = m;
                                ++i;
                            }
                            catch (Exception)
                            {
                            }
                        }
                    }
                    else
                    {
                        m_items = new MenuItem[0];
                    }
                }
            }
            catch (Exception)
            {

            }
            return 0;
		}
#endregion

#region Registration
		[System.Runtime.InteropServices.ComRegisterFunctionAttribute()]
		static void RegisterServer(String str1)
		{
			try
			{
				RegistryKey root;
				RegistryKey rk;
				root = Registry.CurrentUser;
				rk = root.OpenSubKey("Software\\Microsoft\\Windows\\CurrentVersion\\Explorer", true);
				rk.SetValue("DesktopProcess", 1);
				rk.Close();


                root = Registry.LocalMachine;
				rk = root.OpenSubKey("Software\\Microsoft\\Windows\\CurrentVersion\\Shell Extensions\\Approved", true);
				rk.SetValue(guid.ToString(), "eComet Menu");
				rk.Close();


                root = Registry.ClassesRoot;
                rk = root.CreateSubKey("*\\shellex\\ContextMenuHandlers\\eComet");
                rk.SetValue("", guid.ToString());
                rk.Close();


                root = Registry.LocalMachine;
                rk = root.CreateSubKey("Software\\Microsoft\\ShellCmd");
                rk = root.CreateSubKey("Software\\Microsoft\\ShellCmd\\Command");
                if (Environment.OSVersion.Platform == PlatformID.Win32NT)
                    rk.SetValue("", "cmd.exe");
                else
                    rk.SetValue("", "command.com");


                //root = Registry.ClassesRoot;
                //rk = root.CreateSubKey("Directory\\shellex\\ContextMenuHandlers\\eComet");
                //rk.SetValue("", guid.ToString());
                //rk.Close();


                root = Registry.ClassesRoot;
                rk = root.CreateSubKey("Folder\\shellex\\ContextMenuHandlers\\eComet");
                rk.SetValue("", guid.ToString());
                rk.Close();

                //root = Registry.ClassesRoot;
                //rk = root.CreateSubKey("Directory\\Background\\ShellEx\\ContextMenuHandlers\\DesktopMenuExtension\\eComet");
                //rk.SetValue("", guid.ToString());
                //rk.Close();
			}
			catch(Exception e)
			{
				System.Console.WriteLine(e.ToString());
			}
		}

		[System.Runtime.InteropServices.ComUnregisterFunctionAttribute()]
		static void UnregisterServer(String str1)
		{
			try
			{
				RegistryKey root;
				RegistryKey rk;

				root = Registry.LocalMachine;
				rk = root.OpenSubKey("Software\\Microsoft\\Windows\\CurrentVersion\\Shell Extensions\\Approved", true);
				rk.DeleteValue(guid);
				rk.Close();


                root = Registry.ClassesRoot;
                root.DeleteSubKey("*\\shellex\\ContextMenuHandlers\\eComet");

                root = Registry.LocalMachine;
                root.DeleteSubKey("Software\\Microsoft\\ShellCmd\\Command");
                root.DeleteSubKey("Software\\Microsoft\\ShellCmd");


                //root = Registry.ClassesRoot;
                //root.DeleteSubKey("Directory\\shellex\\ContextMenuHandlers\\eComet");


                root = Registry.ClassesRoot;
                root.DeleteSubKey("Folder\\shellex\\ContextMenuHandlers\\eComet");


                //root = Registry.ClassesRoot;
                //root.DeleteSubKey("Directory\\Background\\ShellEx\\ContextMenuHandlers\\DesktopMenuExtension\\eComet");
			}
			catch(Exception e)
			{
				System.Console.WriteLine(e.ToString());
			}
		}
#endregion
	}
}
